package com.texaco.chapasFutbol.multiplayer.mensajes;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public abstract class BaseMessage implements IMessage, Serializable{

	private static final long serialVersionUID = 333218323875504983L;

	protected JSONObject message;
	protected int order;
	
	private BaseMessage(int idMessage, JSONObject message){
		this.message = message;
		try {
			this.message.put(ID_MESSAGE, idMessage);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		read();
	}
	
	protected BaseMessage(int idMessage, String jsonString) throws JSONException{
		this(idMessage, new JSONObject(jsonString));
	}
	
	protected BaseMessage(int idMessage) throws JSONException{
		this(idMessage, new JSONObject());
	}
	
	protected BaseMessage(int idMessage, Map<String, String> jsonMap) throws JSONException{
		this(idMessage, new JSONObject(jsonMap));
	}
	
	public String toString(){
		write();
		return message.toString();
	}
	
	/**
	 * Requiere implementar la lectura de los campos desde el mensaje json.
	 */
	protected abstract void preRead();
	
	/**
	 * Requiere implementar la escritura de los campos desde al mensaje json.
	 */
	protected abstract void preWrite();
	
	public final void read(){
		preRead();
		try {
			order = getInt(ORDER_MESSAGE);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	public final void write(){
		preWrite();
		try {
			message.put(ORDER_MESSAGE, String.valueOf(order));
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Obtiene todos los parametros del objeto json en un mapa
	 * @return
	 * @throws JSONException 
	 */
	public Map<String, String> getMap() throws JSONException{
		write();
		Map<String, String> map = new HashMap<String, String>();
		String key;
		String value = null;
		Iterator<String> it = message.keys();
		while(it.hasNext()){
			key = it.next();
			Object obj = message.get(key);
			if(obj instanceof String){
				value = (String) obj;
			}else{
				value = String.valueOf(obj);
			}
			map.put(key, value);
		}
		return map;
	}
	
	protected int getInt(String key) throws JSONException{
		String strValue = message.optString(key);
		if(strValue != null && strValue.length() != 0){
			return Integer.valueOf(strValue);
		}
		return 0;
	}
	
	protected long getLong(String key) throws JSONException{
		String strValue = message.optString(key);
		if(strValue != null && strValue.length() != 0){
			return Long.valueOf(strValue);
		}
		return 0;
	}
	
	protected String getStr(String key) throws JSONException{
		return message.optString(key);
	}
	
	protected double getDouble(String key) throws JSONException{
		String strValue = message.optString(key);
		if(strValue != null && strValue.length() != 0){
			return Double.valueOf(strValue);
		}
		return 0;
	}
	
	protected List<Double> getArrayAsDouble(String key) throws JSONException{
		JSONArray jsonArray = message.optJSONArray(key);
		List<Double> res = null;
		if(jsonArray != null){
			res = new ArrayList<Double>();
			for(int i = 0; i < jsonArray.length(); i++){
				res.add(jsonArray.getDouble(i));
			}
		}
		return res;
	}
	
	protected void put(String key, Object value) throws JSONException{
		if(value instanceof List){
			message.put(key, value);
		}else{
			message.put(key, String.valueOf(value));
		}
	}

	public int getOrder() {
		return order;
	}

	public void setOrder(int order) {
		this.order = order;
	}
}
